
#include "LPC15xx.h"

void MPUConfig(void);
void Stack_switch(void);
void _tmain(void);
int main(void)
{
    // 使能MemManage 中断
    SCB->SHCSR |= 1 << 16;
    MPUConfig();
//    Stack_switch();
   _tmain();
}

void _tmain(void)
{
    int i = 100;
    // 调用软件中断进入切换到特权模式
    __asm {
        SVC #2
    };
    
    for(i = 100; i--;);
    // 调用软件中断进入切换到退出模式
    __asm {
        SVC #3
    };
    i = 100;
    for(i = 100; i--;);
    while(1);
}


/*============================================================================*/

#define TEX(x)     ((x & 7) << 19)

#define AP(x)      ((x & 7) << 24)

#define PN_UN               (0X00)
#define PRW_UN              (0X01)
#define PRW_URO             (0X02)
#define PRW_URW             (0X03)
#define PRO_UN              (0X05)
#define PRO_URO             (0X06)

#define S(x)       ((x & 1) << 18)

#define C(x)       ((x & 1) << 17)

#define B(x)       ((x & 1) << 16)

#define SRD(x)     ((x & 0xff) << 8)

#define SIZE(x)    ((x & 0x1f) << 1)

#define XN(x)      ((x & 1) << 28)
 
#define SIZE_32B    (4 )
#define SIZE_64B    (5 )
#define SIZE_128B   (6 )
#define SIZE_256B   (7 )
#define SIZE_512B   (8 )
#define SIZE_1K     (9 )
#define SIZE_2K     (10)
#define SIZE_4K     (11)
#define SIZE_8K     (12)
#define SIZE_16K    (13)
#define SIZE_32K    (14)
#define SIZE_64K    (15)
#define SIZE_128K   (16)
#define SIZE_256K   (17)
#define SIZE_512K   (18)
#define SIZE_1M     (19)
#define SIZE_2M     (20)
#define SIZE_4M     (21)
#define SIZE_8M     (22)
#define SIZE_16M    (23)
#define SIZE_32M    (24)
#define SIZE_64M    (25)
#define SIZE_128M   (26)
#define SIZE_256M   (27)
#define SIZE_512M   (28)
#define SIZE_1G     (29)
#define SIZE_2G     (30)
#define SIZE_4G     (31)

#define ENABLE      (1 << 0)

#define MFlashConfig    (TEX(0) | C(1) | B(0) | S(0) | SIZE(SIZE_128K)) | (AP(PRO_UN)) | (ENABLE) | (SRD(0))  | XN(0)

#define MRamConfig      (TEX(0) | C(1) | B(0) | S(1) | SIZE(SIZE_16K))  | (AP(PRW_UN)) | (ENABLE) | (SRD(0))  | XN(0)

#define TFlashConfig    (TEX(0) | C(1) | B(0) | S(0) | SIZE(SIZE_128K)) | (AP(PRO_URO)) | (ENABLE) | (SRD(0)) | XN(0)

#define TRamConfig      (TEX(0) | C(1) | B(0) | S(1) | SIZE(SIZE_16K))  | (AP(PRW_URW)) | (ENABLE) | (SRD(0)) | XN(0)

#define DeviceConfig    

/*============================================================================*/

#define ADDR(x)    ((x & (~0x1f)))

#define VALID(x)   ((x & 1) << 4)

#define REGION(x)  (x & 0xf)


#define MFlashAddr  (ADDR(0))

#define MRamAddr    (ADDR(0x20000000))    

#define TFlashAddr  (ADDR(0) + 128*1024)

#define TRamAddr    (ADDR(0x20000000) + 16*1024)

/*============================================================================*/
#define PRIVDEFENA  (1 << 2)
#define HFNMIENA    (1 << 1)



#define MPU_TYPE     (*((volatile unsigned int *)0xE000ED90))
#define MPU_CTRL     (*((volatile unsigned int *)0xE000ED94))
#define MPU_RNR      (*((volatile unsigned int *)0xE000ED98))
#define MPU_RBAR     (*((volatile unsigned int *)0xE000ED9C))
#define MPU_RASR     (*((volatile unsigned int *)0xE000EDA0))
#define MPU_RBAR_A1  (*((volatile unsigned int *)0xE000EDA4))
#define MPU_RASR_A1  (*((volatile unsigned int *)0xE000EDA8))
#define MPU_RBAR_A2  (*((volatile unsigned int *)0xE000EDAC))
#define MPU_RASR_A2  (*((volatile unsigned int *)0xE000EDB0))
#define MPU_RBAR_A3  (*((volatile unsigned int *)0xE000EDB4))
#define MPU_RASR_A3  (*((volatile unsigned int *)0xE000EDB8))


void MPUConfig(void)
{
    unsigned int reg;
    reg = MPU_TYPE;
    if (reg & (0xff << 8)) {
        MPU_RNR  = 0;
        MPU_RBAR = TFlashAddr | REGION(0) | VALID(1);
        MPU_RASR = TFlashConfig;
        
        MPU_RNR  = 1;
        MPU_RBAR = TRamAddr | REGION(1) | VALID(1);
        MPU_RASR = TRamConfig;
        
        MPU_RNR  = 2;
        MPU_RBAR = MFlashAddr | REGION(2) | VALID(1);
        MPU_RASR = MFlashConfig;
        
        MPU_RNR  = 3;
        MPU_RBAR = MRamAddr | REGION(3) | VALID(1);
        MPU_RASR = MRamConfig;
        
        MPU_CTRL = PRIVDEFENA | HFNMIENA | ENABLE;
    } else {
        while(1);
    }
}





